package org.vaadinpa.gui.views;

import java.util.List;

import org.vaadinpa.Conf;
import org.vaadinpa.data.Planet;
import org.vaadinpa.data.Resource;
import org.vaadinpa.exceptions.NotEnoughFundsException;
import org.vaadinpa.gui.VaadinPA;
import org.vaadinpa.gui.ViewWithCommands;
import org.vaadinpa.gui.util.NotificationUtil;
import org.vaadinpa.logic.Command;
import org.vaadinpa.logic.CommandHandler;
import org.vaadinpa.logic.commands.AsteroidScanCommand;
import org.vaadinpa.logic.commands.AsteroidScanCreateCommand;

import com.vaadin.ui.AbstractOrderedLayout;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Button.ClickListener;
import com.vaadin.ui.GridLayout;
import com.vaadin.ui.Label;
import com.vaadin.ui.Panel;
import com.vaadin.ui.TextField;
import com.vaadin.ui.themes.Reindeer;

@SuppressWarnings("serial")
public class AsteroidsView extends ViewWithCommands {

	private final Label currentRoids = new Label("", Label.CONTENT_XHTML);
	private final Label scansLeft = new Label();
	private final Label roidsLeft = new Label();

	private Button launchScans;
	private Button initButton;

	private final TextField numNewScansField;
	private final TextField launchScansField;

	private final TextField metalF;
	private final TextField crystalF;
	private final TextField goldF;

	public AsteroidsView() {

		Panel createP = new Panel("Create Scans");
		createP.getContent().setSizeUndefined();
		createP.setSizeUndefined();
		((AbstractOrderedLayout) createP.getContent()).setSpacing(true);
		createP.getContent().addStyleName(Reindeer.LAYOUT_BLACK);

		numNewScansField = new TextField("Create new scans here:");
		createP.addComponent(numNewScansField);
		Button createScans = new Button("Create", new CreateScansListener());
		createP.addComponent(createScans);
		addComponent(createP);

		Panel scanP = new Panel("Launch Scans");
		scanP.getContent().setSizeUndefined();
		scanP.getContent().addStyleName(Reindeer.LAYOUT_BLACK);
		scanP.setSizeUndefined();
		((AbstractOrderedLayout) scanP.getContent()).setSpacing(true);
		addComponent(scanP);

		scansLeft.setWidth("300px");
		scanP.addComponent(scansLeft);
		launchScansField = new TextField("Launch here:");
		scanP.addComponent(launchScansField);
		launchScans = new Button("Launch", new LaunchScansListener());
		scanP.addComponent(launchScans);

		GridLayout l = new GridLayout(4, 3);
		l.setMargin(true);
		l.setSizeUndefined();
		l.setSpacing(true);

		l.addComponent(currentRoids, 0, 0, 3, 0);
		l.addComponent(roidsLeft, 0, 1, 3, 1);

		metalF = new TextField("Metal");
		metalF.setSizeUndefined();
		l.addComponent(metalF, 0, 2);
		crystalF = new TextField("Crystal");
		crystalF.setSizeUndefined();
		l.addComponent(crystalF, 1, 2);
		goldF = new TextField("Gold");
		goldF.setSizeUndefined();
		l.addComponent(goldF, 2, 2);

		initButton = new Button("init", new InitRoidsListener());
		l.addComponent(initButton, 3, 2);
		l.setComponentAlignment(initButton, Alignment.BOTTOM_CENTER);

		Panel initP = new Panel("Init roids", l);
		initP.getContent().addStyleName(Reindeer.LAYOUT_BLACK);
		initP.setSizeUndefined();
		addComponent(initP);

		setSpacing(true);

		reload();
	}

	@Override
	public void reload() {

		super.reload();

		Planet p = VaadinPA.getPlanet();
		if (p.availableRoidScans > 0) {
			scansLeft.setValue("You have " + p.availableRoidScans + " roid scans left");
			launchScans.setEnabled(true);
		} else {
			scansLeft.setValue("You have no roid scans available");
			launchScans.setEnabled(false);
		}

		if (p.roids.get(Resource.NEW) > 0) {
			roidsLeft.setValue("You have " + p.roids.get(Resource.NEW) + " new roids");
			initButton.setEnabled(true);
		} else {
			roidsLeft.setValue("You have no new roids, init here:");
			initButton.setEnabled(false);
		}

		String roids = "Currently you have:";
		for (Resource r : Resource.valuesWithoutNew()) {
			roids += "<br>% % roids producing <b>%</b> resources per tick";
			roids = roids.replaceFirst("%", p.roids.get(r) + "");
			roids = roids.replaceFirst("%", r.toString());
			roids = roids
					.replaceFirst("%", p.roids.get(r) * Conf.ROID_RESOURCE_RATE_NORM_LEVEL[p.level.ordinal()] + "");
		}
		currentRoids.setValue(roids);
	}

	@SuppressWarnings("unchecked")
	@Override
	protected List<? extends Command> getCommands() {
		return CommandHandler.getEvents(AsteroidScanCreateCommand.class, AsteroidScanCommand.class);
	}

	private class CreateScansListener implements ClickListener {
		public void buttonClick(ClickEvent event) {
			try {

				Planet p = VaadinPA.getPlanet();

				int maxScans = Integer.MAX_VALUE;
				for (Resource r : Resource.valuesWithoutNew()) {
					int maxFromThisResource = p.getFunds(r) / Conf.COST_ROID_SCAN[r.ordinal()];
					if (maxFromThisResource < maxScans) {
						maxScans = maxFromThisResource;
					}
				}

				int num = new Integer(numNewScansField.getValue().toString()).intValue();
				if (num > maxScans) {
					num = maxScans;
				}
				if (num > 0) {
					AsteroidScanCreateCommand cmd = new AsteroidScanCreateCommand(p, num);
					CommandHandler.handle(cmd);
				}
			} catch (NumberFormatException e) {
			} catch (NotEnoughFundsException e) {
				NotificationUtil.warn("", "Not enough resources");
			}
			numNewScansField.setValue(0);

			reload();
		}
	}

	private class LaunchScansListener implements ClickListener {
		public void buttonClick(ClickEvent event) {
			try {
				Planet p = VaadinPA.getPlanet();
				int num = new Integer(launchScansField.getValue().toString()).intValue();

				if (num > p.availableRoidScans) {
					num = p.availableRoidScans;
				}
				AsteroidScanCommand cmd = new AsteroidScanCommand(VaadinPA.getPlanet(), num);
				CommandHandler.handle(cmd);
				launchScansField.setValue(0);
			} catch (NumberFormatException e) {
			}

			reload();
		}
	}

	private class InitRoidsListener implements ClickListener {
		public void buttonClick(ClickEvent event) {

			int[] roidsToInit = new int[] { 0, 0, 0 };
			try {
				roidsToInit[0] = new Integer(metalF.getValue().toString()).intValue();
			} catch (NumberFormatException e) {
			}
			try {
				roidsToInit[1] = new Integer(crystalF.getValue().toString()).intValue();
			} catch (NumberFormatException e) {
			}
			try {
				roidsToInit[2] = new Integer(goldF.getValue().toString()).intValue();
			} catch (NumberFormatException e) {
			}

			Planet p = VaadinPA.getPlanet();
			boolean notEnoughFunds = false;
			for (Resource r : Resource.valuesWithoutNew()) {
				try {
					while (roidsToInit[r.ordinal()] > 0) {
						p.convertRoid(r);
						roidsToInit[r.ordinal()]--;
					}
				} catch (NotEnoughFundsException e) {
					// not enough funds, continue with next
					notEnoughFunds = true;
				}
			}

			if (notEnoughFunds) {
				NotificationUtil.notify("", "Not enough funds for all conversions");
			}

			reload();

			metalF.setValue(roidsToInit[0]);
			crystalF.setValue(roidsToInit[1]);
			goldF.setValue(roidsToInit[2]);

		}
	}

	@Override
	public String getTitle() {
		return "Asteroid management";
	}
}
